32.1.1 代理服务器配置#
HTTP/HTTPS 代理#
Claude Code 支持标准的环境变量来配置代理服务器:
HTTPS 代理(推荐)
export HTTPS_PROXY=https://proxy.example.com:8080
HTTP 代理(如果 HTTPS 不可用)
export HTTP_PROXY=http://proxy.example.com:8080
代理白名单(不通过代理的地址)
export NO_PROXY="localhost 127.0.0.1 192.168.1.1 example.com .example.com"
代理配置管理器#
bashpython class ProxyConfigManager: """代理配置管理器""" def __init__(self): self.config = { 'https_proxy': None, 'http_proxy': None, 'no_proxy': [], 'proxy_auth': None } def configure(self, proxy_settings: Dict) -> ConfigResult: """配置代理""" result = ConfigResult() # 设置 HTTPS 代理 if 'https_proxy' in proxy_settings: self.config['https_proxy'] = proxy_settings['https_proxy'] os.environ['HTTPS_PROXY'] = self.config['https_proxy'] result.add_setting('HTTPS_PROXY', self.config['https_proxy']) # 设置 HTTP 代理 if 'http_proxy' in proxy_settings: self.config['http_proxy'] = proxy_settings['http_proxy'] os.environ['HTTP_PROXY'] = self.config['http_proxy'] result.add_setting('HTTP_PROXY', self.config['http_proxy']) # 设置白名单 if 'no_proxy' in proxy_settings: no_proxy_list = ' '.join(proxy_settings['no_proxy']) self.config['no_proxy'] = proxy_settings['no_proxy'] os.environ['NO_PROXY'] = no_proxy_list result.add_setting('NO_PROXY', no_proxy_list) # 验证配置 validation = self._validate_config() result.validation = validation return result def _validate_config(self) -> ValidationResult: """验证配置""" validation = ValidationResult() # 检查代理 URL 格式 for proxy_type in ['https_proxy', 'http_proxy']: proxy_url = self.config.get(proxy_type) if proxy_url: if not self._is_valid_url(proxy_url): validation.add_error( f"Invalid {proxy_type} URL: {proxy_url}" ) # 测试代理连接 if self.config.get('https_proxy'): if not self._test_proxy_connection(self.config['https_proxy']): validation.add_error( "Cannot connect to HTTPS proxy" ) return validation def _is_valid_url(self, url: str) -> bool: """验证 URL 格式""" try: result = urllib.parse.urlparse(url) return all([result.scheme, result.netloc]) except Exception: return False def _test_proxy_connection(self, proxy_url: str) -> bool: """测试代理连接""" try: parsed = urllib.parse.urlparse(proxy_url) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) result = sock.connect_ex((parsed.hostname, parsed.port or 8080)) sock.close() return result == 0 except Exception: return False ### 代理身份验证 #### 基本身份验证 # 在代理 URL 中包含凭据 export HTTPS_PROXY=http://username:password@proxy.example.com:8080 export HTTP_PROXY=http://username:password@proxy.example.com:8080
NTLM/Kerberos 认证
对于需要高级身份验证的代理,建议使用 LLM 网关:
bashbash # 配置 LLM 网关处理代理认证 export ANTHROPIC_BASE_URL=https://llm-gateway.company.com export ANTHROPIC_AUTH_TOKEN=gateway-token ### 代理配置最佳实践 ## 32.1.2 自定义 CA 证书 ### 配置自定义 CA 企业环境通常使用自定义证书颁发机构(CA)来签发内部证书。Claude Code 需要配置以信任这些 CA: # 配置自定义 CA 证书 export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem # 或使用多个证书 export NODE_EXTRA_CA_CERTS=/path/to/ca1.pem:/path/to/ca2.pem
CA 证书管理器#
bashpython class CACertificateManager: """CA 证书管理器""" def __init__(self): self.certificates = [] self.certificate_store = '/etc/ssl/certs' def add_certificate(self, cert_path: str) -> CertResult: """添加 CA 证书""" result = CertResult() # 验证证书 if not self._validate_certificate(cert_path): result.success = False result.error = "Invalid certificate" return result # 复制证书到存储 cert_name = os.path.basename(cert_path) dest_path = os.path.join(self.certificate_store, cert_name) shutil.copy(cert_path, dest_path) self.certificates.append(dest_path) # 更新环境变量 self._update_ca_bundle() result.success = True result.certificate_path = dest_path return result def _validate_certificate(self, cert_path: str) -> bool: """验证证书""" try: with open(cert_path, 'rb') as f: cert_data = f.read() # 使用 OpenSSL 验证 result = subprocess.run( ['openssl', 'x509', '-in', cert_path, '-noout'], capture_output=True ) return result.returncode == 0 except Exception: return False def _update_ca_bundle(self): """更新 CA 包""" cert_paths = ':'.join(self.certificates) os.environ['NODE_EXTRA_CA_CERTS'] = cert_paths ### 证书格式转换 # 将 DER 格式转换为 PEM 格式 openssl x509 -inform der -in certificate.cer -out certificate.pem # 将 PKCS#12 格式转换为 PEM 格式 openssl pkcs12 -in certificate.p12 -out certificate.pem -nodes # 提取证书链 openssl s_client -connect server:port -showcerts
32.1.3 mTLS 身份验证#
mTLS 配置#
对于需要客户端证书身份验证的企业环境:
bashbash # 客户端证书 export CLAUDE_CODE_CLIENT_CERT=/path/to/client-cert.pem # 客户端私钥 export CLAUDE_CODE_CLIENT_KEY=/path/to/client-key.pem # 私钥密码短语(如果加密) export CLAUDE_CODE_CLIENT_KEY_PASSPHRASE="your-passphrase" ### mTLS 配置管理器 class MTLSConfigManager: """mTLS 配置管理器""" def __init__(self): self.config = { 'client_cert': None, 'client_key': None, 'key_passphrase': None } def configure(self, mtls_settings: Dict) -> ConfigResult: """配置 mTLS""" result = ConfigResult() # 设置客户端证书 if 'client_cert' in mtls_settings: cert_path = mtls_settings['client_cert'] if self._validate_certificate(cert_path): self.config['client_cert'] = cert_path os.environ['CLAUDE_CODE_CLIENT_CERT'] = cert_path result.add_setting('CLAUDE_CODE_CLIENT_CERT', cert_path) else: result.add_error("Invalid client certificate") # 设置客户端密钥 if 'client_key' in mtls_settings: key_path = mtls_settings['client_key'] if self._validate_key(key_path): self.config['client_key'] = key_path os.environ['CLAUDE_CODE_CLIENT_KEY'] = key_path result.add_setting('CLAUDE_CODE_CLIENT_KEY', key_path) else: result.add_error("Invalid client key") # 设置密钥密码短语 if 'key_passphrase' in mtls_settings: self.config['key_passphrase'] = mtls_settings['key_passphrase'] os.environ['CLAUDE_CODE_CLIENT_KEY_PASSPHRASE'] = \ mtls_settings['key_passphrase'] result.add_setting('CLAUDE_CODE_CLIENT_KEY_PASSPHRASE', '***') # 验证配置 validation = self._validate_mtls_config() result.validation = validation return result def _validate_key(self, key_path: str) -> bool: """验证私钥""" try: result = subprocess.run( ['openssl', 'rsa', '-in', key_path, '-check', '-noout'], capture_output=True ) return result.returncode == 0 except Exception: return False def _validate_mtls_config(self) -> ValidationResult: """验证 mTLS 配置""" validation = ValidationResult() # 检查证书和密钥是否匹配 if (self.config['client_cert'] and self.config['client_key']): if not self._check_cert_key_match(): validation.add_error( "Certificate and key do not match" ) return validation def _check_cert_key_match(self) -> bool: """检查证书和密钥是否匹配""" try: # 提取证书的公钥模数 cert_result = subprocess.run( ['openssl', 'x509', '-noout', '-modulus', '-in', self.config['client_cert']], capture_output=True, text=True ) # 提取密钥的公钥模数 key_result = subprocess.run( ['openssl', 'rsa', '-noout', '-modulus', '-in', self.config['client_key']], capture_output=True, text=True ) return cert_result.stdout == key_result.stdout except Exception: return False
32.1.4 网络访问要求#
必需的 URL#
Claude Code 需要访问以下 URL:
| URL | 用途 | 协议 |
|---|---|---|
api.anthropic.com | Claude API 端点 | HTTPS |
claude.ai | WebFetch 保护措施 | HTTPS |
statsig.anthropic.com | 遥测和指标 | HTTPS |
sentry.io | 错误报告 | HTTPS |
防火墙配置#
bashpython class FirewallConfigurator: """防火墙配置器""" def __init__(self): self.required_urls = [ 'api.anthropic.com', 'claude.ai', 'statsig.anthropic.com', 'sentry.io' ] def generate_rules(self, firewall_type: str = 'iptables') -> List[str]: """生成防火墙规则""" rules = [] if firewall_type == 'iptables': rules = self._generate_iptables_rules() elif firewall_type == 'aws': rules = self._generate_aws_rules() elif firewall_type == 'gcp': rules = self._generate_gcp_rules() return rules def _generate_iptables_rules(self) -> List[str]: """生成 iptables 规则""" rules = [] for url in self.required_urls: # 解析域名获取 IP try: ips = socket.gethostbyname_ex(url)[2] for ip in ips: rule = f"iptables -A OUTPUT -d {ip} -p tcp --dport 443 -j ACCEPT" rules.append(rule) except socket.gaierror: pass return rules def _generate_aws_rules(self) -> List[str]: """生成 AWS 安全组规则""" rules = [] for url in self.required_urls: # AWS 需要使用 IP 范围 # 这里简化处理,实际需要查询 IP 范围 rule = { 'type': 'egress', 'protocol': 'tcp', 'port': 443, 'destination': url, 'action': 'allow' } rules.append(rule) return rules def _generate_gcp_rules(self) -> List[str]: """生成 GCP 防火墙规则""" rules = [] for url in self.required_urls: rule = { 'direction': 'EGRESS', 'action': 'ALLOW', 'rules': [{ 'protocol': 'tcp', 'ports': ['443'], 'destinationRanges': [self._resolve_ip_range(url)] }] } rules.append(rule) return rules def _resolve_ip_range(self, url: str) -> str: """解析 IP 范围""" # 简化实现,实际需要查询 DNS 或 IP 范围 try: ip = socket.gethostbyname(url) return f"{ip}/32" except socket.gaierror: return "0.0.0.0/0" ### 网络连接测试 class NetworkTester: """网络测试器""" def __init__(self): self.required_urls = [ 'https://api.anthropic.com', 'https://claude.ai', 'https://statsig.anthropic.com' ] def test_all(self) -> NetworkTestResult: """测试所有网络连接""" result = NetworkTestResult() for url in self.required_urls: test_result = self._test_url(url) result.add_result(url, test_result) # 生成报告 result.summary = self._generate_summary(result.results) return result def _test_url(self, url: str) -> URLTestResult: """测试单个 URL""" result = URLTestResult(url=url) try: start_time = time.time() response = requests.get(url, timeout=10) end_time = time.time() result.success = response.status_code == 200 result.latency = (end_time - start_time) * 1000 # ms result.status_code = response.status_code except requests.exceptions.Timeout: result.success = False result.error = "Timeout" except requests.exceptions.ConnectionError: result.success = False result.error = "Connection error" except Exception as e: result.success = False result.error = str(e) return result def _generate_summary(self, results: Dict[str, URLTestResult]) -> str: """生成测试摘要""" total = len(results) successful = sum(1 for r in results.values() if r.success) summary = f"Network Test Summary:\n" summary += f"Total: {total}, Successful: {successful}, Failed: {total - successful}\n\n" for url, result in results.items(): status = "✓" if result.success else "✗" summary += f"{status} {url}: " if result.success: summary += f"OK ({result.latency:.0f}ms)\n" else: summary += f"FAILED ({result.error})\n" return summary